import 'dart:io';

import 'package:extended_sliver/extended_sliver.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:webview_flutter/webview_flutter.dart';

const String scrollHeightJs = '''(function() {
  var height = 0;
  var notifier = window.ScrollHeightNotifier || window.webkit.messageHandlers.ScrollHeightNotifier;
  if (!notifier) return;

  function checkAndNotify() {
    var curr = document.body.scrollHeight;
    if (curr !== height) {
      height = curr;
      notifier.postMessage(height.toString());
    }
  }

  var timer;
  var ob;
  if (window.ResizeObserver) {
    ob = new ResizeObserver(checkAndNotify);
    ob.observe(document.body);
  } else {
    timer = setTimeout(checkAndNotify, 200);
  }
  window.onbeforeunload = function() {
    ob && ob.disconnect();
    timer && clearTimeout(timer);
  };
})();''';

const String scrollToBottomJs = '''(function() {
  var notifier = window.ScrollHeightNotifier || window.webkit.messageHandlers.ScrollHeightNotifier;
  if (!notifier) return;

  const handleScroll = () => {
    // 获取滚动条的高度
    var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
    // 获取页面的可视高度
    var visibleHeight = document.documentElement.clientHeight || document.body.clientHeight;
    // 判断滚动条是否滚到最底部
    if (scrollTop + window.innerHeight >= visibleHeight) {
      notifier.postMessage('1');
    }
  }
  window.addEventListener('scroll', handleScroll);
})();''';

/// 网页加载组件
class WebViewPage extends StatefulWidget {
  /// 本地 html
  final String loadHTML;

  const WebViewPage({
    super.key,
    required this.loadHTML,
  });

  @override
  State<WebViewPage> createState() => _WebViewPageState();
}

class _WebViewPageState extends State<WebViewPage> {
  late final WebViewController _webViewController;
  late final ScrollController _scrollController;
  late final ValueNotifier<double> _scrollHeightNotifier;
  late final ValueNotifier<bool> _canAgreeNotifier;

  @override
  void initState() {
    _webViewController = WebViewController();
    _scrollHeightNotifier = ValueNotifier(0.0);
    _canAgreeNotifier = ValueNotifier(false);

    _scrollController = ScrollController()
      ..addListener(() {
        print(_scrollController.offset);
      });

    WidgetsBinding.instance.addPostFrameCallback((_) async {
      // 处理本地Html
      String fileHtmlContents = await rootBundle.loadString(widget.loadHTML);

      _webViewController
        ..setJavaScriptMode(JavaScriptMode.unrestricted)
        ..setNavigationDelegate(
          NavigationDelegate(
            onPageStarted: (String url) => print('开始加载'),
            onPageFinished: (String url) => _webViewController.runJavaScript(scrollToBottomJs),
            onWebResourceError: (WebResourceError error) {},
            onProgress: (int progress) => print("进度：$progress"),
            onNavigationRequest: (NavigationRequest request) => NavigationDecision.navigate,
          ),
        )
        ..loadHtmlString(fileHtmlContents)
        ..addJavaScriptChannel(
          'ScrollHeightNotifier',
          onMessageReceived: (JavaScriptMessage message) {
            /* final String msg = message.message;
            final double? height = double.tryParse(msg);
            if (height != null) {
              _scrollHeightNotifier.value = height;
              print("高度：$height");
            } */
            print('message：${message.message}');

            final int isBottom = int.parse(message.message);
            if (isBottom == 1 && _canAgreeNotifier.value == false) {
              _canAgreeNotifier.value = true;
            }
          },
        );
    });

    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          /// 头部
          _buildTopView(),

          /// 协议内容
          Expanded(
            child: WebViewWidget(controller: _webViewController),

            /// 这个是获取webView中滚动的内容高度
            /* CustomScrollView(
              controller: _scrollController,
              slivers: [
                ValueListenableBuilder(
                  valueListenable: _scrollHeightNotifier,
                  builder: (context, scrollHeight, child) {
                    return SliverToNestedScrollBoxAdapter(
                      childExtent: scrollHeight,
                      onScrollOffsetChanged: (double scrollOffset) {
                        /* double y = scrollOffset;
                        if (Platform.isAndroid) {
                          // https://github.com/flutter/flutter/issues/75841
                          // y *= window.devicePixelRatio;
                          y *= devicePixelRatio;
                        }
                        _webViewController.scrollTo(0, y.ceil()); */
                      },
                      child: child,
                    );
                  },
                  child: WebViewWidget(controller: _webViewController),
                ),

                SliverFillRemaining(
                  child: WebViewWidget(controller: _webViewController),
                ),
              ],
            ), */
          ),

          /// 底部按钮
          _buildBottomButtons(),
        ],
      ),
    );
  }

  Widget _buildTopView() => Container(
        height: 155,
        color: const Color(0xfff3f3f3),
        padding: const EdgeInsets.only(top: 20),
        child: const Stack(
          clipBehavior: Clip.none,
          children: [
            // 分割线
            Positioned(
              left: 13,
              right: 11,
              bottom: 0,
              child: Divider(
                color: Color(0xffd1d1d1),
                height: 0,
                thickness: 0.5,
              ),
            ),
            // 标题
            Positioned(
              left: 20,
              right: 21,
              top: kToolbarHeight,
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  Text(
                    '同学号隐私协议',
                    style: TextStyle(
                      color: Colors.black,
                      fontSize: 26,
                    ),
                  ),
                ],
              ),
            ),
          ],
        ),
      );

  Widget _buildBottomButtons() => Container(
        padding: const EdgeInsets.only(
          left: 20,
          right: 20,
          bottom: 30,
          top: 10,
        ),
        decoration: BoxDecoration(
          boxShadow: [
            BoxShadow(
              color: const Color(0xfff3f3f3).withOpacity(0.7),
              offset: const Offset(0, -5),
              blurRadius: 10,
            ),
          ],
        ),
        child: Row(
          children: [
            Expanded(
              child: TextButton(
                onPressed: () => print('不同意'),
                style: TextButton.styleFrom(
                  backgroundColor: Colors.teal.withOpacity(0.5),
                ),
                child: const Text(
                  '不同意',
                  style: TextStyle(
                    color: Colors.red,
                    fontSize: 16,
                  ),
                ),
              ),
            ),
            const SizedBox(width: 20),
            Expanded(
              child: ValueListenableBuilder(
                valueListenable: _canAgreeNotifier,
                builder: (context, canAgree, child) {
                  return TextButton(
                    onPressed: canAgree ? () => print('同意') : null,
                    style: TextButton.styleFrom(
                      backgroundColor: canAgree ? Colors.blue : Colors.grey.shade300,
                      foregroundColor: canAgree ? Colors.black : Colors.grey,
                    ),
                    child: child!,
                  );
                },
                child: const Text(
                  '同意',
                  style: TextStyle(
                    fontSize: 16,
                    fontWeight: FontWeight.w300,
                  ),
                ),
              ),
            ),
          ],
        ),
      );
}
